<?php

namespace IDock\Insurance\MACN\Request;

use Exception;
use IDock\Insurance\MACN\MACNEnums;
use IDock\Insurance\MACN\Response\PremiumInquiryResponse;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\Premium\PremiumChargingPileVisitor;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use LogicException;

class PremiumInquiryRequest extends AllMACNRequest
{
    protected $response = PremiumInquiryResponse::class;

    public $requestType = '0012';
    /**
     * @var PremiumInquiryVisitor $visitor
     */
    protected $visitor;

    protected $urlTip = '保费计算接口';

    public $companyCode;

    public $operatorCode;

    public $queryType;

    public $queryDetail;

    public $flag;

    /**
     * @return array
     * @throws Exception
     */
    public function generate(): array
    {
        $data = [
            'baseInfo' => [
                'queryType' => $this->queryType,
                'queryDetail' => $this->queryDetail,
                'flag' => $this->flag,
            ],
            'policyInfo' => [
                'agrtNo' => $this->visitor->getExtInfoVisitor()->argc['agrtNo'] ?? '',
                'productCode' => $this->visitor->getExtInfoVisitor()->argc['productCode'] ?? '',
//                'salesmanCode' => $this->visitor->getExtInfoVisitor()->argc['salesmanCode'] ?? '',
                'virtualOperatorCode' => $this->visitor->getExtInfoVisitor()->argc['virtualOperatorCode'] ?? '',
                'operateDate' => date('Y-m-d'),
                'issueDate' => date('Y-m-d'),
//                'publicStoreCode' => 'wx02160640005',
                'interSalesmanCode' => $this->visitor->getExtInfoVisitor()->argc['subAgrtNo'] ?? '',
                'certificateNo' => $this->visitor->getExtInfoVisitor()->argc['certificateNo'] ?? '',//许可证号
                'agencyName' => $this->visitor->getExtInfoVisitor()->argc['agencyName'] ?? '',//代理人名称
                'argueSolution' => $this->visitor->getExtInfoVisitor()->argc['argueSolution'] ?? '',//争议解决方式
                'companyCode' => $this->visitor->getExtInfoVisitor()->argc['companyCode'] ?? '',//业务归属机构
                'operatorCode' => $this->visitor->getExtInfoVisitor()->argc['operatorCode'] ?? '',//操作员代码
                'partnerId' => '',
                'partnerName' => '',
                'productVersion' => '2020',
                'businessNature' => '20101',
                'contractNo' => '',
                'virtualSalesManCode' => '',
            ],
            'insuredInfo' => [
//                'personName' => $this->visitor->getInsuredVisitor()->name,
//                'identifyType' => MACNEnums::$certificateTypeCode[$this->visitor->getInsuredVisitor()->certificateTypeCode],
//                'identifyNumber' => $this->visitor->getInsuredVisitor()->certificateNo,
//                'personType' => $this->visitor->getInsuredVisitor()->typeCode == 'R1' ? '1' : '2',
                'personName' => $this->visitor->getInsuredVisitor()->name,
                'identifyType' => MACNEnums::$certificateTypeCode[$this->visitor->getInsuredVisitor()->certificateTypeCode],
                'identifyNumber' => $this->visitor->getInsuredVisitor()->certificateNo,
            ],
            'holderInfo' => [
                'personName' => $this->visitor->getApplicantVisitor()->name,
                'identifyType' => MACNEnums::$certificateTypeCode[$this->visitor->getApplicantVisitor()->certificateTypeCode],
                'identifyNumber' => $this->visitor->getApplicantVisitor()->certificateNo,
            ],
            'itemInfo' => $this->getItemInfo(),
            'forceRiskInfo' => $this->getJqData(),
        ];

        if ($this->visitor->getInsuredVisitor()->name != $this->visitor->getOwnerVisitor()->name) {
            $data['insuredInfo']['personName'] = $this->visitor->getInsuredVisitor()->name;
            $data['insuredInfo']['identifyType'] = MACNEnums::$certificateTypeCode[$this->visitor->getInsuredVisitor()->certificateTypeCode];
            $data['insuredInfo']['identifyNumber'] = $this->visitor->getInsuredVisitor()->certificateNo;
        }

        $biData = $this->getBusinessRiskData();
        if (!empty($biData['itemKindList']['itemKindInfo'])) {
            $data['businessRiskInfo'] = $biData;
        }
        if ($this->visitor->isNewEnergy && !empty($this->visitor->getChargingPileVisitorList())) {
            $data['chargingPosts'] = $this->getChargingPostData();
        }
//        if(empty($data['insuredInfo']['identifyType'])){
//            throw new Exception("不支持的证件类型");
//        }
        if (!empty($this->visitor->getExtInfoVisitor()->expectedDiscount)) {
            $data['expectDiscount'] = $this->visitor->getExtInfoVisitor()->expectedDiscount;
        }
        //驾意险
        if ($this->visitor->getNonCarInquiryVisitor()->getNonCarList()) {
            $nonCar = $this->getNonCarList();
            if (!empty($nonCar)) {
                $data['accidentInjuryInss'] = $nonCar;
            }
        }
        //新车备案
        if ($this->visitor->vehicleVisitor->carCertificateType) {
            $data['certificateDateBJ'] = $this->visitor->vehicleVisitor->carCertificateDate ? date('Y-m-d',strtotime($this->visitor->vehicleVisitor->carCertificateDate)) : '';
            $data['certificateType']  = $this->visitor->vehicleVisitor->carCertificateType;
            $data['certificateNo'] = $this->visitor->vehicleVisitor->carCertificateNo;
        }

        return $data;
    }

    /**
     * 车辆信息
     * @return mixed
     */
    public function getItemInfo()
    {
        $vehicle = $this->visitor->getVehicleVisitor();
        $owner = $this->visitor->getOwnerVisitor();
        $arr = [
            'idcardstartdate' => $owner->certificateStartDate,
            'idcardenddate' => $owner->certificateEndDate,
            'completeKerbMass' => round($vehicle->wholeWeight, 2),
            'printBrandName' => $vehicle->argc['brandName'] ?? '',
            'carModelName' => $vehicle->vehicleName,
            //'carKindCodeShow' => '' ,
            'tonCount' => $vehicle->vehicleTonnage,
            'exhaustScale' => $vehicle->vehicleExhaust,
            'power' => $vehicle->power,
            'wholeWeight' => $vehicle->wholeWeight,
            'attachNature' => $owner->typeCode == 'R1' ? '1' : '2',
            'purchasePrice' => $vehicle->vehiclePrice,
            'actualValue' => $vehicle->actualValue,
            'identifyType' => MACNEnums::$certificateTypeCode[$owner->certificateTypeCode],
            'ownerIdentifyNumber' => $owner->certificateNo,
            'carOwner' => $owner->name,
            'plateNum' => $vehicle->licenseNo,
            'isFieldCar' => '',//外地车标志
            'plateColor' => MACNEnums::$licenseColorCode[$vehicle->licenseColorCode],//号牌颜色
            'plateType' => MACNEnums::$licenseTypeCode[$vehicle->licenseTypeCode],//号牌种类
            'frameNo' => $vehicle->vin,
            'engineNum' => $vehicle->engineNo,
            'singeinDate' => $vehicle->firstRegisterDate,
            'isNew' => $vehicle->isNewVehicle ? '1' : '0',
            'enrollDate' => $vehicle->firstRegisterDate,
            'brandName' => $vehicle->vehicleName,
            'modelCode' => $vehicle->vehicleModelCode,
            'colorCode' => MACNEnums::$vehicleColor[$vehicle->vehicleColor] ?? '',//车辆颜色
            'motorType' => MACNEnums::$carKindCode[$vehicle->carKindCode],//车辆类型
            'seatCount' => $vehicle->vehicleSeat,//座位
            'carUseType' => MACNEnums::$causeType[$vehicle->causeType],//车辆用途
            'useNatureShow' => MACNEnums::$useNatureCode[$vehicle->useNatureCode],//使用性质
            'jgVehicleType' => $vehicle->vehicleStyleCode,//交管车辆种类
            'groupCode' => '0',
            'isTransfer' => $vehicle->isCiTransfer ? '1' : '0',
            'notCarChgOwnerFlagComm' => $vehicle->isTransfer ? '0' : '1',
            'isTransferDate' => $vehicle->transferDate,
            'loanVehicleFlag' => '0',
            'runMiles' => '0',
            'carType1' => $vehicle->carKindCode == '100' ? 'A' : 'H',//车辆大类
            'carType2' => '0',//车辆细类
            'carType3' => '0',//车辆子类
            'insuredNature' => $owner->typeCode == 'R1' ? '1' : '2',//车主类别
            'insuredType' => $owner->typeCode == 'R1' ? '3' : '4',//车主类别
            'certificateDate' => $vehicle->issueDate,//发证日期
            'energyFlag' => $vehicle->isNewEnergy ? '1' : '0',//产品类别
            'fuelType' => array_search($vehicle->energyTypeCode, MACNEnums::$energyType),//燃料类型
            'vehicleStyleUniqueId' => $this->visitor->getVehicleVisitor()->argc['vehicleId'] ?? '',//燃料类型
        ];

        if ($arr['insuredNature'] == 2 && in_array($owner->organizationType, ['03', '05', '08', '10', ''])) {
            $arr['insuredType'] = '03';//自然人
        }
        $vehicle->vehicleTonnage = (float)$vehicle->vehicleTonnage;
        if (!(float)$vehicle->vehicleTonnage) {
            $vehicle->vehicleTonnage = 0;
        }
        $arr['carKindCodeShow'] = $this->getCarKindCodeShow($arr['carType1'], $vehicle->vehicleSeat, round($vehicle->vehicleTonnage / 1000, 2));

        $arr = $this->getCarType($arr, $this->visitor->getVehicleVisitor()->argc['carKind'], $vehicle->vehicleSeat, round($vehicle->vehicleTonnage / 1000, 2));

        if (empty($arr['identifyType'])) {
            throw new LogicException("不支持该车主证件类型");
        }
        if (empty($arr['plateType'])) {
            throw new LogicException("不支持该号牌种类");
        }
        if (empty($arr['motorType'])) {
            throw new LogicException("不支持该车辆类型");
        }
        if (empty($arr['carUseType'])) {
            throw new LogicException("不支持该车辆用途");
        }

        return $arr;
    }

    /**
     * 获取车辆类型
     * @param $carType
     * @param $seat
     * @param $vehicleWeight
     * @return string
     */
    private function getCarKindCodeShow($carType, $seat, $vehicleWeight): string
    {
        if ($carType == 'H') {
            $code = '21';
            //货车
            if ($vehicleWeight < 2) {
                return $code;
                //$code = '21';//2吨以下货车
            } elseif ($vehicleWeight < 5) {
                $code = '22';//2-5吨货车
            } elseif ($vehicleWeight < 10) {
                $code = '23';//5-10吨货车
            } else {
                $code = '24';//10吨以上货车
            }
        } else {
            $code = '12';
            //客车
            if ($seat < 6) {
                $code = '11';//6座以下客车
            } elseif ($seat < 10) {
                return $code;
                //$code = '12';//6-10座客车
            } elseif ($seat < 20) {
                return $code;
                //$code = '12';//10-20座客车
            } elseif ($seat < 36) {
                return $code;
                //$code = '12';//20-36座客车
            } else {
                return $code;
                //$code = '12';//36座以上客车
            }
        }
        return $code;
    }

    /**
     * 获取车辆分类
     * @param $arr
     * @param $carKind
     * @param $seat
     * @param $vehicleWeight
     * @return mixed
     */
    private function getCarType($arr, $carKind, $seat, $vehicleWeight)
    {
        if ($arr['carType1'] == 'A') {
            //客车
            $isSUV = strpos($carKind, '越野') !== false;
            if ($seat <= 6) {
                $arr['carType2'] = '01';
                $arr['carType3'] = $isSUV ? '069' : '067';
            } elseif ($seat <= 10) {
                $arr['carType2'] = '02';
                if ($isSUV) {
                    $arr['carType3'] = '069';//越野车
                } elseif (strpos($carKind, '轿车') !== false) {
                    $arr['carType3'] = '067';//轿车
                } else {
                    $arr['carType3'] = '068';//小型客车
                }
            } elseif ($seat <= 20) {
                $arr['carType2'] = '03';
                $arr['carType3'] = '072';
            } elseif ($seat <= 36) {
                $arr['carType2'] = '04';
                $arr['carType3'] = '072';
            } else {
                $arr['carType2'] = '05';
                $arr['carType3'] = '073';
            }

        } else {
            //货车
            if ($vehicleWeight < 2) {
                $arr['carType2'] = '06';
                $arr['carType3'] = '035';
            } elseif ($vehicleWeight < 5) {
                $arr['carType2'] = '07';
                $arr['carType3'] = '035';
            }
        }
        return $arr;
    }

    /**
     * @throws Exception
     */
    private function getJqData(): array
    {
        $tax = $this->visitor->getCarTaxVisitor();
        $arr = [
            'riskCode' => '0806',
            'startDate' => $this->visitor->ciStartData ? date('Y-m-d', strtotime($this->visitor->ciStartData)) : '',
            'endDate' => $this->visitor->ciEndData ? date('Y-m-d', strtotime($this->visitor->ciEndData)) : '',
            'startTime' => '00:00',
            'endTime' => '24:00',
            'effectFlag' => $this->visitor->ciEffectFlag ? '2' : '1',
            'itemKindInfo' => [
                'itemKindNo' => '1',
                'kindCode' => 'BZ',
                'sumInsured' => '200000',
                'rate' => '',
                'unitInsured' => '',
                'quantity' => '',
                'discount' => '',
                'premium' => '',
                'discountPremium' => '',
            ],
            'carShipTaxInfo' => [
//                'startTaxDate' => '',
                'taxpayerCertiType' => MACNEnums::$certificateTypeCode[$tax->taxpayerCertificateTypeCode],//纳税人证件类型
                'lastTaxDate' => $tax->taxStartDate ? date('Y-m-d H:i:s', strtotime('-1 year', strtotime($tax->taxStartDate))) : '',//上年缴税日期
                'taxRegistryNumber' => $tax->taxpayerCertificateNo,//税务登记证号
                'taxStartDate' => $tax->taxStartDate,//税款所属始期
                'taxEndDate' => $tax->taxEndDate,//税款所属止期
                'taxFlag' => MACNEnums::$taxTypeCode[$tax->taxTypeCode],//缴税标志
                'taxDocumentNumber' => $tax->taxDocumentNumber,//完税凭证号码
                'taxDepartmentCode' => '',//完税凭证税务机关代码
                'taxDepartment' => '',//完税凭证税务机关名称
                'taxDocumentDate' => '',//完税凭证填发日期
                'noTaxCarType' => MACNEnums::$taxReductionReasonCode[$tax->taxReductionReasonCode] ?? '',//减免税原因代码
            ],
        ];
        if ($this->visitor->ciStartData) {
            $startTimestamp = strtotime($this->visitor->ciStartData);
            $startTime = mktime(date('H', $startTimestamp), date('i', $startTimestamp), date('s', $startTimestamp), date('m', $startTimestamp), date('d', $startTimestamp), date('Y', $startTimestamp));
            $endTimeStamp = strtotime($this->visitor->ciEndData);
            $endTime = mktime(date('H', $endTimeStamp), date('i', $endTimeStamp), date('s', $endTimeStamp), date('m', $endTimeStamp), date('d', $endTimeStamp), date('Y', $endTimeStamp));
            $arr['startTime'] = date('H:i', $startTime);
            $arr['endTime'] = date('H:i', $endTime);
        }
        if (empty($arr['carShipTaxInfo']['taxFlag'])) {
            throw new Exception("不支持该缴税类型");
        }
        if ($arr['carShipTaxInfo']['taxFlag'] == 'W') {
            //完税
            $arr['carShipTaxInfo']['taxDocumentNumber'] = $tax->taxDocumentNumber;
            $arr['carShipTaxInfo']['taxDepartmentCode'] = $tax->taxDepartmentCode;
            $arr['carShipTaxInfo']['taxDepartment'] = $tax->taxDepartment;
            $arr['carShipTaxInfo']['taxDocumentDate'] = $tax->taxDocumentDate;
        }
        return $arr;
    }

    /**
     * @return array
     * @throws Exception
     */
    private function getBusinessRiskData(): array
    {
        $list = $this->visitor->getCoverageVisitorList();
        $arr = [
            'riskCode' => '0812',
            'startDate' => $this->visitor->biStartData ? date('Y-m-d', strtotime($this->visitor->biStartData)) : '',
            'endDate' => $this->visitor->biEndData ? date('Y-m-d', strtotime($this->visitor->biEndData)) : '',
            'startTime' => '0:0',
            'endTime' => '24:0',
            'effectFlag' => $this->visitor->biEffectFlag ? '2' : '1',
            'itemKindList' => ['itemKindInfo' => []],
        ];
        if ($this->visitor->biStartData) {
            $startTimestamp = strtotime($this->visitor->biStartData);
            $startTime = mktime(date('H', $startTimestamp), date('i', $startTimestamp), date('s', $startTimestamp), date('m', $startTimestamp), date('d', $startTimestamp), date('Y', $startTimestamp));
            $endTimeStamp = strtotime($this->visitor->biEndData);
            $endTime = mktime(date('H', $endTimeStamp), date('i', $endTimeStamp), date('s', $endTimeStamp), date('m', $endTimeStamp), date('d', $endTimeStamp), date('Y', $endTimeStamp));
            $arr['startTime'] = date('H:i', $startTime);
            $arr['endTime'] = date('H:i', $endTime);
        }
        $coverage = [];
        $kindNumber = 1;

        /*** @var PremiumCoverageVisitor $coverageVisitor */
        foreach ($list as $coverageVisitor) {
            if ($coverageVisitor->coverageCode == 'C01001') {
                continue;
            }
            $item = [
                'itemKindNo' => $kindNumber,
                'kindInd' => '2',
                'kindCode' => MACNEnums::$coverageCode[$coverageVisitor->coverageCode],
                'sumInsured' => $coverageVisitor->amount,
                'rate' => $coverageVisitor->rate,
                'unitInsured' => $coverageVisitor->unitAmount,
                'quantity' => $coverageVisitor->quantity,
                'deductible' => $coverageVisitor->deductionLimit,
                'relatedInd' => '0',
            ];

            //车损保额
            if ($item['kindCode'] == 'A') {
                $item['sumInsured'] = $this->visitor->vehicleVisitor->actualValue ?: $this->visitor->vehicleVisitor->negotiatedValue;
            }

            $item['kindName'] = MACNEnums::$kindName[$item['kindCode']];
            if (in_array($item['kindCode'], ['A', 'B', 'D11', 'D12', 'DLJY', 'CLAQ', 'DWJS', 'DWSJ'])) {
                $item['kindInd'] = '1';
            }

            //if ($item['kindCode'] == 'A') {
            //    $item['sumInsured'] = '0.0';
            //}

            if (in_array($item['kindCode'], ['D22', 'D23', 'AD12'])) {
                $item['quantity'] = intval($this->visitor->getVehicleVisitor()->vehicleSeat - 1);
                $item['unitInsured'] = $coverageVisitor->amount;
                $item['sumInsured'] = round($item['quantity'] * $coverageVisitor->amount, 2);
            }

            if ($item['kindCode'] == 'X') {
                throw new Exception('亚太--附加新增加设备损失险--暂未开发,请重新选择');
            }

            //特约次数
            if (in_array($item['kindCode'], ['DLJY', 'CLAQ', 'DWJS', 'DWSJ'])) {
                $item['quantity'] = $coverageVisitor->serviceTimes;
            }
            $coverage[] = $item;
            $kindNumber += 1;
        }
        $arr['itemKindList']['itemKindInfo'] = $coverage;
        return $arr;
    }

    /**
     * 充电桩信息
     * @return array
     */
    private function getChargingPostData(): array
    {
        $list = [];

        $chargeList = $this->visitor->getChargingPileVisitorList();
        /*** @var  $value PremiumChargingPileVisitor */
        foreach ($chargeList as $value) {
            $tmp = [
                'chargingPostType' => $value->chargingPileType,//新能源汽车充电桩型号
                'chargingPostCode' => $value->chargingPileCode,//新能源汽车充电桩编码
                'chargingPostAddress' => $value->chargingPileAddress,//新能源汽车充电桩地址
                'chargingPostKind' => MACNEnums::$chargingPileKind[$value->chargingPileKind],//充电桩种类
                'chargingPostAddressType' => MACNEnums::$chargingPileAddressType[$value->chargingPileAddressType],//充电桩安装地点
                'chargingPostYearLimit' => MACNEnums::$chargingPileYearLimit[$value->chargingPileYearLimit],//充电桩使用年限
                'lossSumLimit' => $value->lossAmount,//充电桩损失险保额
                'liabilitySumLimit' => $value->liabilityAmount,//充电桩责任险保额
            ];
            $list[] = $tmp;
        }
        return ['chargingPost' => $list];
    }

    public function getNonCarList(): array
    {
        $list = [];
        foreach ($this->visitor->getNonCarInquiryVisitor()->getNonCarList() as $item) {
            /*** @var $item NonCarProductVisitor */
            $tmp = [
                'acciCount' => $item->insuredNum,//投保份数
                'proCode' => $item->productCode,
                'isType' => $this->visitor->biStartData ? '2' : '1',//起保日期和商业险相同
            ];
            $list[] = $tmp;
        }
        $arr = [
            'accidentInjuryIns' => $list,
        ];
        return empty($list) ? [] : $arr;
    }

}
